module MaybeCPSMonad where

{-# LANGUAGE InstanceSigs #-}

import MaybeCPS

instance Functor (MaybeCPS r) where
    fmap :: (a -> b) -> MaybeCPS r a -> MaybeCPS r b
    fmap f (MaybeCPS c) = MaybeCPS $ 
        \ks kf -> c (ks . f) kf

instance Applicative (MaybeCPS r) where
    pure :: a -> MaybeCPS r a
    pure x = MaybeCPS $ \ks kf -> ks x
    (<*>) :: MaybeCPS r (a -> b) -> MaybeCPS r a -> MaybeCPS r b
    (MaybeCPS mf) <*> (MaybeCPS c) = MaybeCPS $ 
        \ks kf -> c (\a -> mf (\f -> ks (f a)) kf) kf

instance Monad (MaybeCPS r) where
    (>>=) :: MaybeCPS r a -> (a -> MaybeCPS r b) -> MaybeCPS r b
    (MaybeCPS c) >>= f = MaybeCPS $ 
        \ks kf -> c (\a -> runMaybeCPS (f a) ks kf) kf

{-

instance Functor MaybeCPS where
    fmap :: (a -> b) -> MaybeCPS a -> MaybeCPS b
    fmap f mca = toMaybeCPS $ fmap f $ fromMaybeCPS mca

-- 1. 
-- fmap f mca = toMaybeCPS $ fmap f $ fromMaybeCPS mca

instance Applicative MaybeCPS where
    pure :: a -> MaybeCPS a
    pure x = MaybeCPS (\ks kf -> ks x)
    (<*>) :: MaybeCPS (a -> b) -> MaybeCPS a -> MaybeCPS b
    mf <*> mx = toMaybeCPS (fromMaybeCPS mf <*> fromMaybeCPS mx)

instance Monad MaybeCPS where
    (>>=) :: MaybeCPS a -> (a -> MaybeCPS b) -> MaybeCPS b
    ma >>= f = toMaybeCPS (fromMaybeCPS ma >>= (fromMaybeCPS . f))

    -}

